// (c) 2008 Kickstone Technology Ltd

#include "stdafx.h"
#include <Mshtml.h>
#include "IEVersion.h"

#define MAX_BUF_SZ 1000

CIEVersion::CIEVersion(){
	fetchIEVersion();
}

// get the version using the executable file
int CIEVersion::getIEFileVersion(){
	wchar_t buffer[MAX_BUF_SZ];
	// get the exe file name
	DWORD size=GetModuleFileName(NULL, buffer, MAX_BUF_SZ);
	if (size==0 || size==MAX_BUF_SZ)
		return 0;

	// does it have version info?
	DWORD verHnd;
	DWORD dwVerInfoSize = GetFileVersionInfoSize (buffer, &verHnd);
	if (!dwVerInfoSize)     // Cannot reach the DLL file
		return 0;

	// get the version info structure
	LPSTR lpstrVffInfo = (LPSTR)malloc(dwVerInfoSize);  // Alloc memory for file info
	if (lpstrVffInfo == NULL)
		return 0;   // Allocation failed

	// Try to get the info
	if (!GetFileVersionInfo(buffer, verHnd, dwVerInfoSize, lpstrVffInfo)) {
		free (lpstrVffInfo);
		return 0;	// Cannot read the file information - 
					// wierd, since we could read the information size
	}
	VS_FIXEDFILEINFO *fixed_file_info;
	UINT puLen;
	DWORD versionVerified = VerQueryValue(lpstrVffInfo, TEXT("\\"), (LPVOID*) &fixed_file_info, &puLen);
	if (versionVerified==0){
		free (lpstrVffInfo);
		return 0;
	}

	int fileVer=fixed_file_info->dwFileVersionMS>>16;
	free (lpstrVffInfo);
	return fileVer;
}

// get the version of IE, try the exe first then the html object dll
void CIEVersion::fetchIEVersion(){

	m_ieVer=getIEFileVersion();
	if (m_ieVer==0){

		HINSTANCE dll = LoadLibrary(_T("shdocvw.dll"));
		if (dll) {
			DLLGETVERSIONPROC pDllGetVersion;
			pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(dll, "DllGetVersion");
			if (pDllGetVersion) {
				DLLVERSIONINFO2 dvi = {0};
				dvi.info1.cbSize = sizeof(DLLVERSIONINFO2);
				(*pDllGetVersion)((DLLVERSIONINFO*)&dvi);
				m_ieVer=(dvi.ullVersion>>48)&0xffff;
			}
			FreeLibrary(dll);
		}
	}
}

// alternative version using the browser object
void CIEVersion::fetchIEVersion2(IWebBrowser2 *pWebBrowser2){
	CComPtr<IDispatch>        spDocDisp;
	CComQIPtr<IHTMLDocument2> spHtmlDoc2;
	CComPtr<IHTMLWindow2>   spWindow;
	CComPtr<IOmNavigator>   spNavigator;
	HRESULT hr;
	
	hr= pWebBrowser2->get_Document(&spDocDisp);
	if(SUCCEEDED(hr) && spDocDisp) {
		spHtmlDoc2 = spDocDisp;
		if(spHtmlDoc2) {
			hr = spHtmlDoc2->get_parentWindow(&spWindow);
			if(SUCCEEDED(hr)) {
				hr = spWindow->get_navigator(&spNavigator);
				if(SUCCEEDED(hr)) {
					CComBSTR bstrVersion;
					hr =  spNavigator->get_appVersion(&bstrVersion);
					if(SUCCEEDED(hr)) {
						CHAR szVersion[MAX_PATH];
						memset(szVersion,0,MAX_PATH);

						WideCharToMultiByte(CP_ACP, 0, 
								  bstrVersion.m_str, 
								  -1, szVersion, 
								  MAX_PATH, NULL, NULL);
						if(strstr(szVersion, "MSIE 7.") != NULL)
							m_ieVer=7;
						else
							m_ieVer=6;
					}
				}
			}
		}
	}
}
